package comparesions

import (
	"go_gvm_mini/instructions/base"
	"go_gvm_mini/rtda"
	"reflect"
	"strings"
)

// Branch if int comparison with zero succeeds
type IF_ICMP[T EQ | NE | LT | LE | GE | GT] struct{ base.BranchInstruction }

func (self *IF_ICMP[T]) Execute(jFrame *rtda.JFrame) {
	val2 := jFrame.OperandStack().PopInt()
	val1 := jFrame.OperandStack().PopInt()
	e := reflect.TypeOf(self).Elem().String()
	etype := strings.ReplaceAll(strings.Split(e, "[")[1], "]", "")
	switch etype {
	case "EQ":
		if val1 == val2 {
			base.Branch(jFrame, self.Offset)
		}
		break
	case "NE":
		if val1 != val2 {
			base.Branch(jFrame, self.Offset)
		}
		break
	case "LT":
		if val1 < val2 {
			base.Branch(jFrame, self.Offset)
		}
		break
	case "LE":
		if val1 <= val2 {
			base.Branch(jFrame, self.Offset)
		}
		break
	case "GT":
		if val1 > val2 {
			base.Branch(jFrame, self.Offset)
		}
		break
	case "GE":
		if val1 >= val2 {
			base.Branch(jFrame, self.Offset)
		}
		break
	}
}

type IF_ICMPEQ struct {
	IF_ICMP[EQ]
}

type IF_ICMPNE struct {
	IF_ICMP[NE]
}

type IF_ICMPLT struct {
	IF_ICMP[LT]
}
type IF_ICMPLE struct {
	IF_ICMP[LE]
}

type IF_ICMPGT struct {
	IF_ICMP[GE]
}
type IF_ICMPGE struct {
	IF_ICMP[GE]
}
